/*
 * Copyright (c) 2006-2021, Ulandlink Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-12-12     zkw         first version
 */

#include <rtthread.h>
#include <sys/time.h>
#include "os_evt.h"
#include "app_websocket_mgnt_sm.h"
#include "app_websocket_mgnt_util.h"
#include "app_websocket_mgnt_mp.h"
#include "app_websocket_ocpp_drv.h"

#define LOG_TAG "ocpp.websocket.sm"
#define LOG_LVL LOG_LVL_INFO
#include "ulog.h"

typedef struct
{
    UINT8 u8CurMod;
    UINT8 u8Retry;
    UINT16 u16Cnt;
    UINT8 send_result;
} app_webclient_sm_info_t;

static app_webclient_sm_info_t app_webclient_sm_info = {0};
static struct os_evt_param webcleint_tx_evt;
static struct os_evt_param webcleint_rx_evt;

static UINT8 app_webclient_tx_idle(UINT8 evt, void *pt_buffer);
static UINT8 app_webclient_rx_idle(UINT8 evt, void *pt_buffer);

// websocket  tx  处理
static const os_evt_tab_t app_webclient_tx_sm_tab[E_APP_WEBCLIENT_TX_STA_MAX] =
    {
        {"webclient_tx_idle", app_webclient_tx_idle},
};

// websocket  rx  处理
static const os_evt_tab_t app_webclient_rx_sm_tab[E_APP_WEBCLIENT_RX_STA_MAX] =
    {
        {"webclient_rx_idle", app_webclient_rx_idle},
};
/******************************************************************************
** Function Name:
**      app_webclient_sm_evt_proc
** Function Description:
**      switch status
** Inputs:
**      ull_app_webclient_tx_evt_e evt, void * pt_buffer
** Returns:
**      None
******************************************************************************/
void app_webclient_tx_sm_evt_proc(ull_app_webclient_tx_evt_e evt, void *pt_buffer) {
    os_evt_proc(&webcleint_tx_evt, (UINT8)evt, pt_buffer);
}
/******************************************************************************
** Function Name:
**      app_webclient_sm_evt_proc
** Function Description:
**      switch status
** Inputs:
**      ull_app_webclient_tx_evt_e evt, void * pt_buffer
** Returns:
**      None
******************************************************************************/
void app_webclient_rx_sm_evt_proc(ull_app_webclient_rx_evt_e evt, void *pt_buffer) {
    os_evt_proc(&webcleint_rx_evt, (UINT8)evt, pt_buffer);
}

/******************************************************************************
 ** Function Name:
 **      app_webclient_idle
 ** Function Description:
 **      State Machine - idle
 ** Inputs:
 **      UINT8 evt
 **      void *pt_buffer
 ** Returns:
 **      UINT8 ret,next status
 ******************************************************************************/
static UINT8 app_webclient_tx_idle(UINT8 evt, void *pt_buffer) {
    UINT8 ret = E_APP_WEBCLIENT_TX_STA_IDLE;
    UINT8 i = 1;
    bool send_ret = false;
    app_webclient_sm_info_t *ptsminfo = &app_webclient_sm_info;
    os_mq_data *pt_msg = (os_mq_data *)pt_buffer;
    struct app_websocket_msg_data_t *pt_web = (struct app_websocket_msg_data_t *)pt_msg->mq_pt_data;

    switch (evt) {
    case E_APP_WEBCLIENT_TX_EVT_INIT:
        // ptsminfo->u16Cnt = 50;
        break;

    case E_APP_WEBCLINET_EVT_OCPP_MSG: {

        if (pt_web->ocpp_req_type >= E_OCPP_SEND_ACTION_MAX) {
            break;
        }
        if (E_OCPP_CONNECT == pt_web->ocpp_req_type) {
            if (app_webclient_util_conn() != TRUE) {
                app_webclient_util_close();
            }
        } else {
            app_ocpp_util_send_proc(E_OCPP_MESSAGE_CALL, pt_web->ocpp_req_type, 0, RT_NULL);
        }

    } break;
    case E_APP_WEBCLINET_EVT_DATA_RECV: {
        if (E_OCPP_GET_CONFIGURATION == pt_web->ocpp_resp_type) {
            send_ret = app_ocpp_util_send_proc(E_OCPP_MESSAGE_CALL_RESULT, pt_web->ocpp_resp_type, pt_web->ocpp_param_type, RT_NULL);
            LOG_D("send proc:%d", pt_web->ocpp_param_type);
        } else {
            send_ret = app_ocpp_util_send_proc(E_OCPP_MESSAGE_CALL_RESULT, pt_web->ocpp_resp_type, pt_web->ocpp_resp_result, pt_web->ocpp_iso_resp_type);
        }
    } break;

    case E_APP_WEBCLINET_EVT_15118_MSG: {
        LOG_I("E_APP_WEBCLINET_EVT_15118_MSG: %d", pt_web->ocpp_iso_req_type);
        send_ret = app_ocpp_util_send_proc(E_OCPP_MESSAGE_CALL, pt_web->ocpp_req_type, 0, pt_web->ocpp_iso_req_type);
    } break;
    default:
        break;
    }
    return ret;
}

/******************************************************************************
** Function Name:
**      app_webclient_tx_sm_init
** Function Description:
**      init
** Inputs:
**      None
** Returns:
**      None
******************************************************************************/
void app_webclient_tx_sm_init(void) {
    memset(&app_webclient_sm_info, 0, sizeof(app_webclient_sm_info));
    os_evt_init(&webcleint_tx_evt, "webclient_tx_sm", app_webclient_tx_sm_tab,
                E_APP_WEBCLIENT_TX_STA_IDLE,
                E_APP_WEBCLIENT_TX_STA_MAX,
                E_APP_WEBCLIENT_TX_EVT_MAX);

    app_webclient_tx_sm_evt_proc(E_APP_WEBCLIENT_TX_EVT_INIT, NULL);
}

/******************************************************************************
 ** Function Name:
 **      app_webclient_rx_idle
 ** Function Description:
 **      State Machine - idle
 ** Inputs:
 **      UINT8 evt
 **      void *pt_buffer
 ** Returns:
 **      UINT8 ret,next status
 ******************************************************************************/
static UINT8 app_webclient_rx_idle(UINT8 evt, void *pt_buffer) {
    UINT8 ret = E_APP_WEBCLIENT_RX_STA_IDLE;
    UINT8 i = 1;
    os_mq_data *pt_msg = (os_mq_data *)pt_buffer;
    app_websocket_recv_msg_data_t *pdata = (app_websocket_recv_msg_data_t *)pt_msg->mq_pt_data;

    switch (evt) {
    case E_APP_WEBCLIENT_RX_EVT_INIT:

        break;
    case E_APP_WEBCLINET_RX_EVT_RECV: {

        if (pdata->web_msg_type == E_OCPP_MESSAGE_CALL_RESULT) {
            app_ocpp_util_recv_proc(pdata->web_msg_type,
                                    pdata->payload, pdata->ocpp_uid,
                                    pdata->ocpp_action);
        } else if (pdata->web_msg_type == E_OCPP_MESSAGE_CALL) {
            app_ocpp_util_recv_proc(pdata->web_msg_type,
                                    pdata->payload, pdata->ocpp_uid,
                                    pdata->ocpp_action);
        } else {
        }

    } break;

    default:
        break;
    }
    return ret;
}

/******************************************************************************
** Function Name:
**      app_webclient_rx_sm_init
** Function Description:
**      init
** Inputs:
**      None
** Returns:
**      None
******************************************************************************/

void app_webclient_rx_sm_init(void) {
    //    memset(&app_webclient_sm_info, 0, sizeof(app_webclient_sm_info));
    os_evt_init(&webcleint_rx_evt, "webclient_rx_sm", app_webclient_rx_sm_tab,
                E_APP_WEBCLIENT_RX_STA_IDLE,
                E_APP_WEBCLIENT_RX_STA_MAX,
                E_APP_WEBCLIENT_RX_EVT_MAX);

    app_webclient_rx_sm_evt_proc(E_APP_WEBCLIENT_RX_EVT_INIT, NULL);
}
